// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Components/ControllerComponent.h"
#include "LyraCharacterPartTypes.h"

#include "LyraControllerComponent_CharacterParts.generated.h"

class APawn;
class ULyraPawnComponent_CharacterParts;
class UObject;
struct FFrame;

// 角色部件来源枚举
enum class ECharacterPartSource : uint8
{
	Natural, // 自然的

	NaturalSuppressedViaCheat, // 通过作弊抑制的自然部件

	AppliedViaDeveloperSettingsCheat, // 通过开发者设置作弊应用的部件

	AppliedViaCheatManager // 通过作弊管理器应用的部件
};

//////////////////////////////////////////////////////////////////////

/**
 * 控制器组件上请求的角色部件条目
 */
USTRUCT()
struct FLyraControllerCharacterPartEntry
{
	GENERATED_BODY()

	FLyraControllerCharacterPartEntry()
	{}

public:
	// 所代表的角色部件
	UPROPERTY(EditAnywhere, meta=(ShowOnlyInnerProperties))
	FLyraCharacterPart Part;

	FLyraCharacterPartHandle Handle; // 如果已应用于Pawn，则为对应的句柄

	ECharacterPartSource Source = ECharacterPartSource::Natural; // 此部件的来源
};

//////////////////////////////////////////////////////////////////////

/**
 * 一个组件，用于配置当拥有控制器占据一个Pawn时要为该控制器生成哪些化妆角色
 */
UCLASS(meta = (BlueprintSpawnableComponent))
class ULyraControllerComponent_CharacterParts : public UControllerComponent
{
	GENERATED_BODY()

public:
	ULyraControllerComponent_CharacterParts(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());

	//~UActorComponent 接口
	virtual void BeginPlay() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
	//~UActorComponent 接口结束

	/**
	 * 将角色部件添加给拥有此定制组件的角色，应仅在权限端调用
	 */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Cosmetics)
	void AddCharacterPart(const FLyraCharacterPart& NewPart);

	/**
	 * 从拥有此定制组件的角色移除先前添加的角色部件，应仅在权限端调用
	 */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Cosmetics)
	void RemoveCharacterPart(const FLyraCharacterPart& PartToRemove);

	/**
	 * 移除所有已添加的角色部件，应仅在权限端调用
	 */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Cosmetics)
	void RemoveAllCharacterParts();

	// 如果处于PIE中，则应用相关的开发者设置
	void ApplyDeveloperSettings();

protected:
	UPROPERTY(EditAnywhere, Category=Cosmetics)
	TArray<FLyraControllerCharacterPartEntry> CharacterParts; // 角色部件列表

private:
	ULyraPawnComponent_CharacterParts* GetPawnCustomizer() const;

	UFUNCTION()
	void OnPossessedPawnChanged(APawn* OldPawn, APawn* NewPawn);

	void AddCharacterPartInternal(const FLyraCharacterPart& NewPart, ECharacterPartSource Source);

	void AddCheatPart(const FLyraCharacterPart& NewPart, bool bSuppressNaturalParts);
	void ClearCheatParts();

	void SetSuppressionOnNaturalParts(bool bSuppressed);

	friend class ULyraCosmeticCheats;
};